;
; Startup code for cc65 (C64 16k CRT)
; No IRQ support at the moment
;

		.export         _exit
		.export         __STARTUP__ : absolute = 1      ; Mark as startup

		.import _main

		.import initlib, donelib, copydata
		.import zerobss
		.import __RAM_START__, __RAM_SIZE__     ; Linker generated
		.import __DATA_SIZE__, __DATA_LOAD__, __DATA_RUN__
		.import __EAPI_START__, __EAPIRAM_START__

		.include "zeropage.inc"
		.include "c64.inc"

EASYFLASH_BANK    = $DE00
EASYFLASH_CONTROL = $DE02
EASYFLASH_LED     = $80
EASYFLASH_16K     = $07
EASYFLASH_KILL    = $04


; ------------------------------------------------------------------------
; Place the startup code in a special segment.

.segment           "STARTUP"


CINT   = $ff81
IOINIT = $ff84
RAMTAS = $ff87
RESTOR = $ff8a

		.addr	cold_start
		.addr	warm_start
		.byte   "CBM80"

cold_start:		
		ldx #0
		stx $d016
		jsr IOINIT
		jsr RAMTAS
		jsr RESTOR
		jsr CINT

		cli

		jsr zerobss
		
warm_start:
		; Switch to second charset
		lda #14
		jsr $FFD2

		jsr copydata
		
		ldx #$00
eapi_loop:
		lda __EAPI_START__, x
		sta __EAPIRAM_START__, x
		lda __EAPI_START__ + $100, x
		sta __EAPIRAM_START__ + $100, x
		lda __EAPI_START__ + $200, x
		sta __EAPIRAM_START__ + $200, x
		dex
		bne eapi_loop

		; and here
		; Set argument stack ptr
		lda #<(__RAM_START__ + __RAM_SIZE__)
		sta sp
		lda #>(__RAM_START__ + __RAM_SIZE__)
		sta sp + 1

		jsr initlib

		lda #$01
		sta $d020
		sta $d021

		jsr _main

_exit:
		jsr donelib
exit:
		jmp (reset_vector) ; reset, mhhh


; ------------------------------------------------------------------------
; This code is executed in Ultimax mode. It is called directly from the
; reset vector and must do some basic hardware initializations.
; It also contains trampoline code which will switch to 16k cartridge mode
; and call the normal startup code.
;
        .segment "ULTIMAX"
.proc ultimax_reset
ultimax_reset:
        ; === the reset vector points here ===
        sei
        ldx #$ff
        txs
        cld

        ; enable VIC (e.g. RAM refresh)
        lda #8
        sta $d016

        ; write to RAM to make sure it starts up correctly (=> RAM datasheets)
wait:
        sta $0100, x
        dex
        bne wait

        ; copy the final start-up code to RAM (bottom of CPU stack)
        ldx #(trampoline_end - trampoline)
l1:
        lda trampoline, x
        sta $0100, x
        dex
        bpl l1
        jmp $0100

trampoline:
        ; === this code is copied to the stack area, does some inits ===
        ; === scans the keyboard and kills the cartridge or          ===
        ; === starts the main application                            ===
        lda #EASYFLASH_16K + EASYFLASH_LED
        sta EASYFLASH_CONTROL

        ; Check if one of the magic kill keys is pressed
        ; This should be done in the same way on any EasyFlash cartridge!

        ; Prepare the CIA to scan the keyboard
        lda #$7f
        sta $dc00   ; pull down row 7 (DPA)

        ldx #$ff
        stx $dc02   ; DDRA $ff = output (X is still $ff from copy loop)
        inx
        stx $dc03   ; DDRB $00 = input

        ; Read the keys pressed on this row
        lda $dc01   ; read coloumns (DPB)

        ; Restore CIA registers to the state after (hard) reset
        stx $dc02   ; DDRA input again
        stx $dc00   ; Now row pulled down

        ; Check if one of the magic kill keys was pressed
        and #$e0    ; only leave "Run/Stop", "Q" and "C="
        cmp #$e0
        bne kill    ; branch if one of these keys is pressed

        ; Branch to the normal start-up code
        jmp cold_start

kill:
        lda #EASYFLASH_KILL
        sta EASYFLASH_CONTROL
        jmp (reset_vector) ; reset
trampoline_end:
.endproc

        .segment "VECTORS"
.word   0
reset_vector:
.word   ultimax_reset
.word   0 ;irq

 